/**
 *  涉及到了
 * 1. 异步编程
 * 2. 事件循环
 * 3. this指向
 * 4. 作用域
 * 5. 变量提升
 * 6. 闭包
 * 7. 原型
 * 8. 继承
 *  */

// 异步编程
// 题1
function Test1() {
	const promise = new Promise((resolve, reject) => {
		console.log(1);
		console.log(2);
	});

	promise.then(() => {
		console.log(3);
	});
	console.log(4);
}
// Test1()
// 1 2 4
/**
 * 解析：
 * prmise.then是微任务，在所有宏任务执行完之后才会执行
 * 因为promise一直pending，所以不输出3
 */

// 题2
function Test2(params) {
	const promise1 = new Promise((resolve, rejct) => {
		console.log('promise1');
		resolve('resolve1');
	});

	const promise2 = promise1.then((res) => {
		console.log(res);
	});
	console.log('1', promise1);
	console.log('2', promise2);
}
// Test2()
// 结果：promise1
// 1 Promise {<fulfilled>: 'resolve1'}
// 2 Promise {<pending>}
// resolve1

// 题3
function Test3() {
	const promise = new Promise((resolve, reject) => {
		console.log(1);
		setTimeout(() => {
			console.log('timerStart');
			resolve('success');
			console.log('timerEnd');
		}, 0);
		console.log(2);
	});
	promise.then((res) => {
		console.log(res);
	});
	console.log(4);
}
// Test3()
// 结果：1 2 4 timerStart timerEnd success

// 题4
function Test4() {
	Promise.resolve().then(() => {
		console.log('promise1');
		const timer2 = setTimeout(() => {
			console.log('timer2');
		}, 0);
	});
	const timer1 = setTimeout(() => {
		console.log('timer1');
		Promise.resolve().then(() => {
			console.log('promise2');
		});
	}, 0);
	console.log('start');
}
// Test4()
// 结果：start promise1 timer1 promise2 timer2

// 题5
function Test5() {
	const promise = new Promise((resolve, reject) => {
		resolve('success1');
		reject('error');
		resolve('success2');
	});
	promise
		.then((res) => {
			console.log('then:', res);
		})
		.catch((err) => {
			console.log('catch:', err);
		});
}
// Test5()
// 结果: then:success1

// 题6
function Test6() {
	Promise.resolve(1).then(2).then(Promise.resolve(3)).then(console.log);
}
// Test6();
// 结果：1
/**
 * 解析：Promise.resolve自动为原始值返回新的Promise对象
 * then方法接收的参数是函数，如果传入的不是函数，则将其解释为then(null)
 */

// 题7
function Test7() {
	const promise1 = new Promise((resolve, reject) => {
		setTimeout(() => {
			resolve('success');
		}, 1000);
	});
	const promise2 = promise1.then(() => {
		throw new Error('error!!!');
	});
	console.log('promise1', promise1);
	console.log('promise2', promise2);
	setTimeout(() => {
		console.log('promise1', promise1);
		console.log('promise2', promise2);
	}, 2000);
}
// Test7()
/**
 * 结果： 
 * promise1 Promise {<pending>}
 * promise2 Promise {<pending>}
 * 
 * promise1 Promise {<fulfilled>: 'success'}
 * promise2 Promise {<rejected>: Error: error!!!}
 */

// 题8
function Test8() {
	Promise.resolve(1)
		.then((res) => {
			console.log(res);
			return 2;
		})
		.catch((err) => {
			return 3;
		})
		.then((res) => {
			console.log(res);
		});
}
// Test8()
// 结果：1 2
// .then的回调会返回一个新的promise，从而实现了链式调用

// 题9
function Test9() {
	Promise.resolve()
		.then(() => {
			return new Error('error!!!');
		})
		.then((res) => {
			console.log('then:', res);
		})
		.catch((err) => {
			console.log('catch:', err);
		});
}
// Test9()
// 结果：then: Error: error!!!
// 解析返回一个非Promise的值都会被包裹成Promise

// 题10
function Test10() {
	const promise = Promise.resolve().then(() => {
		return promise;
	});
	promise.catch(console.err);
}
// Test10()
// 结果：test.html:1 Uncaught (in promise) TypeError: Chaining cycle detected for promise #<Promise>
// 解析，then或者catch不能返回promise本身，否则会造成死循环

// 题11
function Test11() {
	Promise.reject('err!!!')
		.then(
			(res) => {
				console.log('success', res);
			},
			(err) => {
				console.log('error', err);
			}
		)
		.catch((err) => {
			console.log('catch', err);
		});
}
// Test11()
// 结果： error err!!!
/**
 * 解析：
 * 错误被then的第二个参数捕获了，所以就不能被catch了
 */

function Test12() {
	Promise.resolve('1')
		.then((res) => {
			console.log(res);
		})
		.finally(() => {
			console.log('finally');
		});

	Promise.resolve('2')
		.finally(() => {
			console.log('finally2');
			return '我是finally2返回的值';
		})
		.then((res) => {
			console.log('finally2后面的then函数', res);
		});
}
// Test12();
// 结果：1
// finally2
// finally
// finally2后面的then函数 2
/**
 * 解析：finally方法不管Promise对象状态如何都会执行
 * finally不接收任何参数，无法得知promise的状态
 * 它最终返回的是上一个Promise对象值，如果抛出异常则返回异常的Promise对象
 * finally是then方法的特例
 */

// 题13
function Test13() {
	function runAsync(x) {
		const p = new Promise((r) =>
			setTimeout(() => {
				r(x, console.log(x));
			}, 1000)
		);
		return p;
	}
	Promise.all([ runAsync(1), runAsync(2), runAsync(3) ]).then((res) => console.log(res));
}
// Test13();
// 结果：
// 1
// 2
// 3
// [1, 2,3 ]
/**
 * 解析：
 */

// 题14
function Test14() {
	function runAsync(x) {
		const p = new Promise((r) =>
			setTimeout(() => {
				r(x, console.log(x));
			}, 1000)
		);
		return p;
	}
	function runReject(x) {
		const p = new Promise((res, rej) =>
			setTimeout(() => {
				rej(`Error:${x}`, console.log(x));
			}, 1000 * x)
		);
		return p;
	}
	Promise.all([ runAsync(1), runReject(4), runAsync(3), runReject(2) ])
		.then((res) => console.log(res))
		.catch((err) => console.log(err));
}
// Test14();
// 结果：
// 1
// 3
// 2
// Error:2
// 4

/**
 * 解析：如果一组异步操作中有一个异常都不会进入.then的第一个回调函数，会被第二个回调捕获
 */

// 题15
function Test15() {
	function runAsync(x) {
		const p = new Promise((r) =>
			setTimeout(() => {
				r(x, console.log(x));
			}, 1000)
		);
		return p;
	}
	Promise.race([ runAsync(1), runAsync(2), runAsync(3) ])
		.then((res) => console.log('result:', res))
		.catch((err) => console.log(err));
}
// Test15();
// 结果：
// 1
// result 1
// 2
// 3
/**
 * 解析：then只会捕获第一个成功的方法，其他的函数虽然继续执行，但是不被then捕获了
 */

// 题16
function Test16() {
	function runAsync(x) {
		const p = new Promise((r) =>
			setTimeout(() => {
				r(x, console.log(x));
			}, 1000)
		);
		return p;
	}
	function runReject(x) {
		const p = new Promise((res, rej) =>
			setTimeout(() => {
				rej(`Error:${x}`, console.log(x));
			}, 1000 * x)
		);
		return p;
	}
	Promise.race([ runAsync(0), runReject(1), runAsync(2), runReject(3) ])
		.then((res) => console.log(res))
		.catch((err) => console.log(err));
}
// Test16()
// 结果：
// 0
// 0
// 1
// 2
// 3
/**
 * 解析：Promise完成后，后续抛出的错误将不会再捕获
 */

// 题17
function Test17() {
	function runAsync(x) {
		const p = new Promise((r) =>
			setTimeout(() => {
				r(x, console.log(x));
			}, 1000)
		);
		return p;
	}
	function runReject(x) {
		const p = new Promise((res, rej) =>
			setTimeout(() => {
				rej(`Error:${x}`, console.log(x));
			}, 1000 * x)
		);
		return p;
	}
	Promise.race([ runReject(0), runAsync(1), runAsync(2), runReject(3) ])
		.then((res) => console.log(res))
		.catch((err) => console.log(err));
}
// Test17()
// 结果：
// 0
// Error:0
// 1
// 2
// 3
/**
 * 解析：all和race中如果有抛出异常的异步任务，只有最先抛出的被捕获，但不会影响数组中其他异步任务的执行
 */

// 题18
function Test18() {
	async function async1() {
		console.log('async1 start');
		await async2();
		console.log('async1 end');
	}
	async function async2() {
		console.log('async2');
	}
	async1();
	console.log('start');
}
// Test18()
// 结果：
// async1 start
// async2
// start
// async1 end
/**
 * 解析：await后的语句相当于在new Promise中，下一行的语句相当于放在Promise.then中
 */

// 题19
function Test19() {
	async function async1() {
		console.log('async1 start');
		await async2();
		console.log('async1 end');
		setTimeout(() => {
			console.log('timer1');
		}, 0);
	}
	async function async2() {
		setTimeout(() => {
			console.log('timer2');
		}, 0);
		console.log('async2');
	}
	async1();
	setTimeout(() => {
		console.log('timer3');
	}, 0);
	console.log('start');
}
// Test19()
// 结果：
// async1 start
// async2
// start
// async1 end
// timer2
// timer3
// timer1
//
/**
 * 解析：
 */

// 题20
function Test20() {
	async function async1() {
		console.log('async1 start');
		await new Promise((resolve) => {
			console.log('promise1');
		});
		console.log('async1 success');
		return 'async1 end';
	}
	console.log('script start');
	async1().then((res) => console.log(res));
	console.log('script end');
}
// Test20()
// 结果：
// script start
// async1 start
// promise1
// script end
/**
 * 解析：Promise一直pending所以await后面的内容不会执行，包括async1的then中
 */

// 题21
function Test21() {
	async function async1() {
		console.log('async1 start');
		await new Promise((resolve) => {
			console.log('promise1');
			resolve('promise1 resolve');
		}).then((res) => console.log(res));
		console.log('async1 success');
		return 'async1 end';
	}
	console.log('script start');
	async1().then((res) => console.log(res));
	console.log('script end');
}
// Test21()
// 结果：
// script start
// async1 start
// promise1
// script end
// promise1 resolve
// async1 success
// ‘async1 end
/**
 * 解析：
 */

// 题22
function Test22() {
	async function async1() {
		console.log('async1 start');
		await async2();
		console.log('async1 end');
	}
	async function async2() {
		console.log('async2');
	}
	console.log('script start');
	setTimeout(() => {
		console.log('setTimeout');
	}, 0);
	async1();
	new Promise((resolve) => {
		console.log('promise1');
		resolve();
	}).then(function() {
		console.log('promise2');
	});
	console.log('script end');
}
// Test22()
// 结果：
// script start
// async1 start
// async2
// promise1
// script end
// async1 end
// promise2
// setTimeout
//
/**
 * 解析：
 */

// 题23
function Test23() {
	async function async1() {
		await async2();
		console.log('async1');
		return 'async1 success';
	}
	async function async2() {
		return new Promise((resolve, reject) => {
			console.log('async2');
			reject('error');
		});
	}
	async1().then((res) => console.log(res));
}
// Test23()
// 结果：
// async2
// Uncaught (in promise) error
/**
 * 解析：async函数抛出错误，不会继续往下执行，可以用catch捕获错误
 */

// 题24
function Test24() {
	async function async1() {
		await async2().catch((e) => console.log(e));
		console.log('async1');
		return 'async1 success';
	}
	async function async2() {
		return new Promise((resolve, reject) => {
			console.log('async2');
			reject('error');
		});
	}
	async1().then((res) => console.log(res));
}
// Test24()
// 结果：
// async2
// error
// async1
// async1 success
/**
 * 解析：async函数抛出错误，不会继续往下执行，可以用catch捕获错误
 */

// 题25
function Test25() {
	const first = () =>
		new Promise((resolve, reject) => {
			console.log(3);
			let p = new Promise((resolve, reject) => {
				console.log(7);
				setTimeout(() => {
					console.log(5);
					resolve(6);
					console.log(p);
				}, 0);
				resolve(1);
			});
			resolve(2);
			p.then((arg) => {
				console.log(arg);
			});
		});
	first().then((arg) => {
		console.log(arg);
	});
	console.log(4);
}
// Test25()
// 结果：
// 3
// 7
// 4
// 1
// 2
// 5
// Promise {<fulfilled>: 1}
/**
 * 解析：resolve之后的代码也会执行的
 */

// 题26
function Test26() {
	const async1 = async () => {
		console.log('async1');
		setTimeout(() => {
			console.log('timer1');
		}, 2000);
		await new Promise((resolve) => {
			console.log('promise1');
		});
		console.log('async1 end');
		return 'async1 success';
	};
	console.log('script start');
	async1().then((res) => console.log(res));
	console.log('script end');
	Promise.resolve(1).then(2).then(Promise.resolve(3)).catch(4).then((res) => console.log(res));
	setTimeout(() => {
		console.log('timer2');
	}, 1000);
}
// Test26();
// 结果：
// script start
// async1
// promise1
// script end
// 1
// timer2
// timer1
/**
 * 解析：
 */

// 题27
function Test27() {
	const p1 = new Promise((resolve) => {
		setTimeout(() => {
			resolve('resolve3');
			console.log('timer1');
		}, 0);
		resolve('resolve1');
		resolve('resolve2');
	})
		.then((res) => {
			console.log(res);
			setTimeout(() => {
				console.log(p1);
			}, 1000);
		})
		.finally((res) => {
			console.log('finally', res);
		});
}
// Test27()
// 结果：
// resolve1
// finally undefined
// timer1
// Promise {<fulfilled>: undefined}
/**
 * 解析：
 */

// 题28
function Test28() {
	console.log(1);
	setTimeout(() => {
		console.log(2);
		process.nextTick(function() {
			console.log(3);
		});
		new Promise(function(resolve) {
			console.log(4);
			resolve();
		}).then(function() {
			console.log(5);
		});
	});
	process.nextTick(function() {
		console.log(6);
	});
	new Promise(function(resolve) {
		console.log(7);
		resolve();
	}).then(function() {
		console.log(8);
	});
	setTimeout(() => {
		console.log(9);
		process.nextTick(function() {
			console.log(10);
		});
		new Promise(function(resolve) {
			console.log(11);
			resolve();
		}).then(function() {
			console.log(12);
		});
	});
}
// Test28();
// 结果：
// 1
// 7
// 6
// 8
// 2
// 4
// 3
// 5
// 9
// 11
// 10
// 12
/**
 * 解析：
 */

// 题29
function Test29() {
	console.log(1);
	setTimeout(() => {
		console.log(2);
	});
	new Promise((resolve) => {
		console.log(3);
		resolve(4);
	}).then((d) => console.log(d));

	setTimeout(() => {
		console.log(5);
		new Promise((resolve) => {
			resolve(6);
		}).then((d) => console.log(d));
	});

	setTimeout(() => {
		console.log(7);
	});
	console.log(8);
}
// Test29();
// 结果：
// 1
// 3
// 8
// 4
// 2
// 5
// 6
// 7
/**
 * 解析：
 */

// 题29
function Test29() {
	console.log(1);
	setTimeout(() => {
		console.log(2);
		Promise.resolve().then(() => {
			console.log(3);
		});
	});

	new Promise((resolve, reject) => {
		console.log(4);
		resolve(5);
	}).then((data) => {
		console.log(data);
	});

	setTimeout(() => {
		console.log(6);
	});
	console.log(7);
}
// Test29();
// 结果：
// 1
// 4
// 7
// 5
// 2
// 3
// 6
/**
 * 解析：
 */

// 题30
function Test30() {
	Promise.resolve()
		.then(() => {
			console.log(1);
			throw 'Error';
		})
		.then(() => {
			console.log(2);
		})
		.catch(() => {
			console.log(3);
			throw 'Error';
		})
		.then(() => {
			console.log(4);
		})
		.catch(() => {
			console.log(5);
		})
		.then(() => {
			console.log(6);
		});
}
// Test30();
// 结果：
// 1
// 3
// 5
// 6
/**
 * 解析：
 */


// 题31
function Test31() {
    setTimeout(() => {
        console.log(1);
    }, 100);
    new Promise(function (resolve) {
        console.log(2);
        resolve()
        console.log(3);
    }).then(function () {
        console.log(4);
        new Promise((resolve, reject) => {
            console.log(5);
            setTimeout(() => {
                console.log(6);
            }, 10);
        })
    })
    console.log(7);
    console.log(8);
}
Test31()
// 结果：
// 2
// 3
// 7
// 8
// 4
// 5
// 6
// 1
/**
 * 解析：
 */